﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

//*************************************************************************************************
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
//*************************************************************************************************

//*************************************************************************************************
namespace TCP_Client_Test
{
    public partial class Form1 : Form
    {
        /****************************************************************************************/
        public byte[] StringToHex(string s)
        {//string转Hex
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
            {
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            }

            return buffer;
        }
        /****************************************************************************************/
        public string HexToString(byte[] data)
        {//Hex转String
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
            {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            }

            return sb.ToString().ToUpper();
        }
        /****************************************************************************************/
        TcpClient   tcpClient;
        Thread      TCP_Rev_T;
        int RX_Pack = 0;
        int RX_Byte = 0;
        public Form1()
        {
            InitializeComponent();
        }
        private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {//设置ip仅允许输入数字和.
                if (((e.KeyChar >= '0') && (e.KeyChar <= '9')) || (e.KeyChar == '.') || (e.KeyChar == '\b'))
                {
                    e.Handled = false;
                }
                else
                {
                    MessageBox.Show("请输入数字");
                    e.Handled = true;
                    return;
                }
        }
        private void textBox2_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {//设置端口号仅允许输入数字
            if ((e.KeyChar >= '0') && (e.KeyChar <= '9') || (e.KeyChar == '\b'))
            {
                    e.Handled = false;
                }
                else
                {
                    MessageBox.Show("请输入数字");
                    e.Handled = true;
                    return;
                }
        }
        private void textBox4_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {//设置为HEX发送接收时仅允许 空格 / 删除 / 0-9 / A-F
            if (radioButton1.Checked)
            {
                if (((e.KeyChar >= '0') && (e.KeyChar <= '9')) || (e.KeyChar == ' ') || (e.KeyChar == '\b')
                    || ((e.KeyChar >= 'a') && (e.KeyChar <= 'f'))|| ((e.KeyChar >= 'A') && (e.KeyChar <= 'F')))
                {
                    e.Handled = false;
                }
                else
                {
                    MessageBox.Show("请输入16进制值");
                    e.Handled = true;
                    return;
                }
            }
            else
            {
                e.Handled = false;
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            textBox3.Text = null;
            RX_Pack = 0;
            RX_Byte = 0;
            label6.Text = "0";
            label8.Text = "0";
        }
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                tcpClient.Close();
            }
            catch { }
            try
            {
                System.Environment.Exit(0);
            }
            catch { }
        }
        //TCP Client 连接 *************************************************************************
        private void button1_Click(object sender, EventArgs e)
        {//TCP 连接
            if (button1.Text == "连接")
            {
                tcpClient = new TcpClient();
                string ServerIP = textBox1.Text;
                string ServerPort = textBox2.Text;

                if ((ServerIP != String.Empty && ServerIP.Length != 0)&&(ServerPort != String.Empty && ServerPort.Length != 0))
                {
                    button1.Enabled = false;
                    button1.Text = "等待连接";
                    try
                    {
                        var result = tcpClient.BeginConnect(IPAddress.Parse(textBox1.Text), Int32.Parse(textBox2.Text), null, null);
                        var sucess = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(3));
                        if (sucess)
                        {
                            tcpClient.NoDelay = true;
                            TCP_Rev_T = new Thread(TCP_Receive);
                            TCP_Rev_T.Start();
                            textBox1.Enabled = false;
                            textBox2.Enabled = false;
                            button1.Text = "断开";
                            button2.Enabled = true;
                        }
                        else
                        {
                            tcpClient.Close();
                            textBox3.Text = "连接超时，未连接到指定服务器，请检查连接";
                            button1.Text = "连接";
                        }
                        button1.Enabled = true;
                    }
                    catch
                    {
                        MessageBox.Show("连接错误,请检查服务器IP与端口号");
                        button1.Text = "连接";
                        button1.Enabled = true;
                    }
                }
                else
                {
                    Form2 form2 = new Form2();
                    if (ServerIP == String.Empty || ServerIP.Length == 0)
                    {
                        form2.label1.Text = "请输入服务器IP";
                    }
                    else if (ServerPort == String.Empty || ServerPort.Length == 0)
                    {
                        form2.label1.Text = "请输入服务器端口号";
                    }
                    form2.ShowDialog();
                }
            }
            else
            {
                textBox1.Enabled = true;
                textBox2.Enabled = true;
                tcpClient.Close();
                button1.Text = "连接";
            }
        }
        //TCP Client 发送 *************************************************************************
        private void button2_Click(object sender, EventArgs e)
        {//TCP 发送
            string TCP_Send = textBox4.Text;//读取用户的输入
            NetworkStream ns = tcpClient.GetStream();

            //将字符串转化为字节数组，然后发送到服务器端
            if (ns.CanWrite)
            {
                Byte[] sendBytes = null;
                if (radioButton1.Checked)
                {
                    sendBytes = StringToHex(TCP_Send);
                }
                else if (radioButton2.Checked)
                {
                    sendBytes = Encoding.ASCII.GetBytes(TCP_Send);
                }
                else if (radioButton3.Checked)
                {
                    sendBytes = Encoding.UTF8.GetBytes(TCP_Send);
                }
                else if (radioButton4.Checked)
                {
                    sendBytes = Encoding.Default.GetBytes(TCP_Send);
                }
                ns.Write(sendBytes, 0, sendBytes.Length);
            }
        }
        //TCP Client 接收 *************************************************************************
        private void TCP_Receive(object obj)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            Socket socket_R = tcpClient.Client;
            NetworkStream ns = tcpClient.GetStream();
            int MaxLen = socket_R.ReceiveBufferSize;
            while (true)
            {
                //System.Threading.Thread.Sleep(1);
                if (ns.CanRead)
                {
                    string s = Get_TCP_Data(socket_R, 100, MaxLen);
                    if (s.Length != 0)
                    {
                        RX_Pack++;
                        string display = "\r\nReceive:" + s + "\r\n";
                        textBox3.Text += display;
                        this.textBox3.SelectionStart = this.textBox3.Text.Length;
                        this.textBox3.ScrollToCaret();
                        label6.Text = RX_Pack.ToString();
                        label8.Text = RX_Byte.ToString();
                    }
                }
            }
        }
        // 获取TCP数据 ****************************************************************************
        public string Get_TCP_Data(Socket socket, int timeout , int max_len)
        { 
            string result = string.Empty;
            socket.ReceiveTimeout = timeout;
            byte[] buffer = new byte[max_len];
            List<Byte> data = new List<Byte>();
            data.Clear();
            int length = 0;

            try
            {
                while ((length = socket.Receive(buffer)) > 0)
                {
                    for (int i = 0; i < length; i++)
                    {
                        data.Add(buffer[i]);
                    }
                    break;
                }
            }
            catch
            {
                
            }
            if ((data != null)&&(data.Count > 0))
            {
                RX_Byte += data.Count;
                if (radioButton1.Checked)
                {
                    result = HexToString(data.ToArray());
                }
                else if (radioButton2.Checked)
                {
                    result = Encoding.ASCII.GetString(data.ToArray());
                }
                else if (radioButton3.Checked)
                {
                    result = Encoding.UTF8.GetString(data.ToArray());
                }
                else if (radioButton4.Checked)
                {
                    result = Encoding.Default.GetString(data.ToArray());
                }
            }
            return result;
        }

        private void button4_Click(object sender, EventArgs e)
        {//打开文件
            OpenFileDialog OFD = new OpenFileDialog();
            OFD.Title = "打开第一个文本文件";
            OFD.FileName = "*.BLdata";
            OFD.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
            if (OFD.ShowDialog() == DialogResult.OK)
            {
                FileInfo fi = new FileInfo(OFD.FileName);
                StreamReader sr = fi.OpenText();
                textBox3.Text = OFD.FileName + "\r\n";
                textBox3.Text += sr.ReadToEnd();
                sr.Close();
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            SaveFileDialog SFD = new SaveFileDialog();
            SFD.Title = "保存文本文件至";
            SFD.FileName = "*.BLdata";
            SFD.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
            if (SFD.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(SFD.FileName, FileMode.Create, FileAccess.Write);
                //File.WriteAllText(SFD.FileName, textBox3.Text);
                StreamWriter sw = new StreamWriter(fs); 
                sw.Write(textBox3.Text);
                sw.Close();
                fs.Close();
            }
        }

    }
}
